﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Bymed.SpineScan.WPF.Model;
using Bymed.SpineScan.WPF.Shared;
using Bymed.SpineScan.WPF.ViewModel.TestItemViewModel;
using Bymed.SpineScan.DataModel;
using Bymed.SpineScan.Service.Shared;

namespace Bymed.SpineScan.WPF.ViewModel
{
    public class SelectTestItemViewModel : AllTestItemsAndPatientInfoViewModel
    {
        public const string GoToNextPageMessageToken = "SelectTestItemGoToNextPageMessage";
        public const string GenuineCheckFailedMessageToken = "SelectTestItemGenuineCheckFailedMessage";

        /// <summary>
        /// Initializes a new instance of the SelectTestItemViewModel class.
        /// </summary>
        public SelectTestItemViewModel(IDataService dataService)
            : base(dataService) { }

        public override void ResetProperties()
        {
            try
            {
                base.ResetProperties();

                var availableAuthorisedUsagedCount = GeneralUtility.GetAvailableAuthorisedUsageCount();

                if (availableAuthorisedUsagedCount == 0)
                {
                    // Send GenuineCheckFailedMessage to MainViewModel
                    Messenger.Default.Send<int>(0, GenuineCheckFailedMessageToken);
                }

                ViewModelHelper.ResetSingleTestItemViewModel(ScoliosisATI);
                ViewModelHelper.ResetSingleTestItemViewModel(Kyphosis);
                ViewModelHelper.ResetSingleTestItemViewModel(CervicalLateralBending);
                ViewModelHelper.ResetSingleTestItemViewModel(ThoracicLateralBending);
                ViewModelHelper.ResetSingleTestItemViewModel(LumbarLateralBending);
                ViewModelHelper.ResetSingleTestItemViewModel(CervicalFlexExt);
                ViewModelHelper.ResetSingleTestItemViewModel(ThoracicFlexExt);
                ViewModelHelper.ResetSingleTestItemViewModel(LumbarFlexExt);
                ViewModelHelper.ResetSingleTestItemViewModel(CervicalRotation);
                ViewModelHelper.ResetSingleTestItemViewModel(ThoracicRotation);
                ViewModelHelper.ResetSingleTestItemViewModel(LumbarRotation);
                ViewModelHelper.ResetSingleTestItemViewModel(HeadBalance);
                ViewModelHelper.ResetSingleTestItemViewModel(ShouldersBalance);
                ViewModelHelper.ResetSingleTestItemViewModel(PelvicBalance);

                LoadAttendingDoctorList();

                IsSwitchToOriginalTestItems = true;
                SelectedCustomizedTestItemList.Clear();

                InitializePredefinedCustomizedTestItemList();
            }
            catch (Exception ex)
            {
                RequestDisplayErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// The <see cref="AttendingDoctorList" /> property's name.
        /// </summary>
        public const string AttendingDoctorListPropertyName = "AttendingDoctorList";

        private ObservableCollection<AttendingDoctor> _attendingDoctorList = new ObservableCollection<AttendingDoctor>();

        /// <summary>
        /// Sets and gets the AttendingDoctorList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<AttendingDoctor> AttendingDoctorList
        {
            get
            {
                return _attendingDoctorList;
            }

            set
            {
                if (_attendingDoctorList == value)
                {
                    return;
                }

                RaisePropertyChanging(AttendingDoctorListPropertyName);
                _attendingDoctorList = value;
                RaisePropertyChanged(AttendingDoctorListPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="IsSwitchToOriginalTestItems" /> property's name.
        /// </summary>
        public const string IsSwitchToOriginalTestItemsPropertyName = "IsSwitchToOriginalTestItems";

        private bool _isSwitchToOriginalTestItems = true;

        /// <summary>
        /// Sets and gets the IsSwitchToOriginalTestItems property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool IsSwitchToOriginalTestItems
        {
            get
            {
                return _isSwitchToOriginalTestItems;
            }

            set
            {
                if (_isSwitchToOriginalTestItems == value)
                {
                    return;
                }

                RaisePropertyChanging(IsSwitchToOriginalTestItemsPropertyName);
                _isSwitchToOriginalTestItems = value;
                RaisePropertyChanged(IsSwitchToOriginalTestItemsPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="IsSwitchToCustomizedTestItems" /> property's name.
        /// </summary>
        public const string IsSwitchToCustomizedTestItemsPropertyName = "IsSwitchToCustomizedTestItems";

        private bool _isSwitchToCustomizedTestItems = false;

        /// <summary>
        /// Sets and gets the IsSwitchToCustomizedTestItems property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool IsSwitchToCustomizedTestItems
        {
            get
            {
                return _isSwitchToCustomizedTestItems;
            }

            set
            {
                if (_isSwitchToCustomizedTestItems == value)
                {
                    return;
                }

                RaisePropertyChanging(IsSwitchToCustomizedTestItemsPropertyName);
                _isSwitchToCustomizedTestItems = value;
                RaisePropertyChanged(IsSwitchToCustomizedTestItemsPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="PredefinedCustomizedTestItemList" /> property's name.
        /// </summary>
        public const string PredefinedCustomizedTestItemListPropertyName = "PredefinedCustomizedTestItemList";

        private ObservableCollection<CustomizedTestItem> _predefinedCustomizedTestItemList = new ObservableCollection<CustomizedTestItem>();

        /// <summary>
        /// Sets and gets the PredefinedCustomizedTestItemList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<CustomizedTestItem> PredefinedCustomizedTestItemList
        {
            get
            {
                return _predefinedCustomizedTestItemList;
            }

            set
            {
                if (_predefinedCustomizedTestItemList == value)
                {
                    return;
                }

                RaisePropertyChanging(PredefinedCustomizedTestItemListPropertyName);
                _predefinedCustomizedTestItemList = value;
                RaisePropertyChanged(PredefinedCustomizedTestItemListPropertyName);
            }
        }

        private RelayCommand<CustomizedTestItem> _addCustomizedTestItemCommand;

        /// <summary>
        /// Gets the AddCustomizedTestItemCommand.
        /// </summary>
        public RelayCommand<CustomizedTestItem> AddCustomizedTestItemCommand
        {
            get
            {
                return _addCustomizedTestItemCommand ?? (_addCustomizedTestItemCommand = new RelayCommand<CustomizedTestItem>(
                    ExecuteAddCustomizedTestItemCommand,
                    CanExecuteAddCustomizedTestItemCommand));
            }
        }

        private void ExecuteAddCustomizedTestItemCommand(CustomizedTestItem parameter)
        {
            PredefinedCustomizedTestItemList.Remove(parameter);
            SelectedCustomizedTestItemList.Insert(0, parameter);
        }

        private bool CanExecuteAddCustomizedTestItemCommand(CustomizedTestItem parameter)
        {
            return parameter == null ? false : true;
        }

        private RelayCommand<CustomizedTestItem> _removeCustomizedTestItemCommand;

        /// <summary>
        /// Gets the RemoveCustomizedTestItemCommand.
        /// </summary>
        public RelayCommand<CustomizedTestItem> RemoveCustomizedTestItemCommand
        {
            get
            {
                return _removeCustomizedTestItemCommand ?? (_removeCustomizedTestItemCommand = new RelayCommand<CustomizedTestItem>(
                    ExecuteRemoveCustomizedTestItemCommand,
                    CanExecuteRemoveCustomizedTestItemCommand));
            }
        }

        private void ExecuteRemoveCustomizedTestItemCommand(CustomizedTestItem parameter)
        {
            SelectedCustomizedTestItemList.Remove(parameter);
            PredefinedCustomizedTestItemList.Insert(0, parameter);
        }

        private bool CanExecuteRemoveCustomizedTestItemCommand(CustomizedTestItem parameter)
        {
            return parameter == null ? false : true;
        }

        private RelayCommand _nextCommand;

        /// <summary>
        /// Gets the NextCommand.
        /// </summary>
        public RelayCommand NextCommand
        {
            get
            {
                return _nextCommand ?? (_nextCommand = new RelayCommand(
                    ExecuteNextCommand,
                    CanExecuteNextCommand));
            }
        }

        private void ExecuteNextCommand()
        {
            // Send to GoToNextPageMessage SelectTestItemPage
            GenerateSelectedTestItemList();

            Messenger.Default.Send<SelectTestItemViewModel>(this, GoToNextPageMessageToken);
        }

        private bool CanExecuteNextCommand()
        {
            // If user does not select any Test item.
            if (ScoliosisATI.IsSelected || Kyphosis.IsSelected || CervicalFlexExt.IsSelected || ThoracicFlexExt.IsSelected || LumbarFlexExt.IsSelected ||
                CervicalLateralBending.IsSelected || ThoracicLateralBending.IsSelected || LumbarLateralBending.IsSelected || CervicalRotation.IsSelected ||
                ThoracicRotation.IsSelected || LumbarRotation.IsSelected || HeadBalance.IsSelected || ShouldersBalance.IsSelected || PelvicBalance.IsSelected || 
                SelectedCustomizedTestItemList.Any())
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Load attending doctor list for binding.
        /// </summary>
        private void LoadAttendingDoctorList()
        {
            AttendingDoctorList = new ObservableCollection<AttendingDoctor>(ServiceFactory.CreateAttendingDoctorService().GetAll().OrderBy(d => d.OrderIndex));
        }

        /// <summary>
        /// Load the data from data source for initializing PredefinedCustomizedTestItemList. 
        /// </summary>
        private void InitializePredefinedCustomizedTestItemList()
        {
            var customizedTestItemList = ServiceFactory.CreateCustomizedTestItemService().GetAll().OrderBy(m => m.OrderIndex);
            PredefinedCustomizedTestItemList = new ObservableCollection<CustomizedTestItem>(customizedTestItemList);
        }
    }
}
